from . import passport_blue
from flask import request,jsonify,current_app,make_response,session
from info.utils.response_code import RET
from info.utils.captcha.captcha import captcha
from info import redis_store,constants,models,db
import re,random,datetime
from info.models import User
from info.libs.yuntongxun.sms import CCP



@passport_blue.route('/image_code')
def generate_image_code():


    # 获取参数
    image_code_id=request.args.get('image_code_id')
    if not image_code_id:
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')
    name,text,image=captcha.generate_captcha()
    try:
        # 缓存uuid并且给其设置有效时长
        redis_store.setex('ImageCode_'+image_code_id,constants.IMAGE_CODE_REDIS_EXPIRES,text)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='保存数据失败')
    response=make_response(image)
    # response['content']
    return response



@passport_blue.route('/sms_code',methods=['POST'])
def send_sms_code():
    mobile=request.json.get('mobile')
    image_code=request.json.get('image_code')
    image_code_id=request.json.get('image_code_id')
    # 检查数据完整性
    if not all([mobile,image_code,image_code_id]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数错误')
    # 匹配手机号
    if  not re.match('1[3456789]\d{9}$',mobile):
        return jsonify(errno=RET.DATAERR,errmsg='手机号格式错误')
    # 获取uuid
    try:
        real_image_code=redis_store.get('ImageCode_'+image_code_id)
    except Exception as e:
        # 没获取到uuid,记录日志
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取数据失败')
    # 如果uuid为空值，有效期到期了
    if not real_image_code:
        return jsonify(errno=RET.DBERR,errmsg='数据过期')
    try:
        # 如过获取到uuid,删除uuid
        redis_store.delete('ImageCode_'+image_code_id)
    except Exception as e:
        current_app.logger.error(e)
    if real_image_code.lower()!=image_code.lower():
        return jsonify(errno=RET.DATAERR,errmsg='验证码错误')
    # 验证码正确，发送短信，用户注册过就不发了，花钱
    # 查询数据库
    try:
        user= User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(essno=RET.DATAERR,errmsg='查询数据库失败')
    else:
        # 查询数据成功，看mobile注册了吗？
        if user is not None:
            return jsonify(essno=RET.DATAEXIST,errmsg='用户已注册')
    # 生成6位数的短信随机码
    sms_code= '%06d' % random.randint(0,999999)
    print(sms_code)
    # 把短信验证码缓存到redis中
    try:
        redis_store.setex('SMSCode_'+mobile,constants.SMS_CODE_REDIS_EXPIRES,sms_code)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='缓存验证码失败')
    # 发验证码
    try:
        ccp=CCP()
        result=ccp.send_template_sms(mobile,[sms_code,constants.SMS_CODE_REDIS_EXPIRES/60],1)

    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.THIRDERR,errmsg='发送信息异常')

    if result == 0:
        return jsonify(errno=RET.OK, errmsg='发送成功')
    else:
        return jsonify(errno=RET.THIRDERR, errmsg='发送失败')
    pass




"""
用户注册---本质是把用户信息写入mysql数据库
获取参数----检查参数----业务处理----返回结果
1、获取参数，mobile，sms_code,password
2、检查参数的完整性
3、检查手机号格式
4、检查短信验证码，尝试从redis中获取真实的短信验证码
5、判断获取结果
6、先比较短信验证码是否正确，因为短信验证码可以比较多次！！比较多次的本质就是可以get数据库多次
7、删除redis中存储的真实短信验证码
8、确认用户未注册
9、使用模型类保存用户数据，密码进行加密存储
10、提交数据到mysql数据库，如果发生异常，需要回滚
11、实现状态保持，缓存用户信息到redis中
12、返回结果

"""
@passport_blue.route('/register',methods=['POST'])
def register():
    # 1
    mobile=request.json.get('mobile')
    sms_code=request.json.get('sms_code')
    password=request.json.get('password')
    # 2
    if not all([mobile,sms_code,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数缺失')
    # 3
    if  not re.match('1[3456789]\d{9}$',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号格式错误')
    # 4
    try:
        real_sms_code=redis_store.get('SMSCode_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='获取短信验证码失败')
    # 5判断查询结果
    if not real_sms_code:
        return jsonify(errno=RET.NODATA,errmsg='短信验证码已经过期')
    # 6
    if sms_code!=real_sms_code:
        return jsonify(errno=RET.DBERR,errmsg='短信验证码错误')
    # 7删除redis中的短信验证码
    try:
        redis_store.delete('SMSCode_'+mobile)
    except Exception as e:
        current_app.logger.error(e)
    # 8从mysql中查看是否注册过，用手机号
    try:
    #     user=User.query.filter(User.mobile==mobile).first()
        user=User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.PARAMERR,errmsg='查询数据失败')
    if  user is not None:
        return jsonify(errno=RET.DATAEXIST,errmsg='用户已经注册')
    '''
    9、使用模型类保存用户数据，密码进行加密存储
    10、提交数据到mysql数据库，如果发生异常，需要回滚
    11、实现状态保持，缓存用户信息到redis中
    12、返回结果
    '''
    # 9
    user=User()
    user.mobile=mobile
    user.password=password
    user.nick_name=mobile
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rolllback()
        return jsonify(errno=RET.DBERR,errmsg='提交数据失败')
    session['user_id']=user.id
    session['mobile']=mobile
    session['nick_name']=mobile
    return jsonify(errno=RET.OK,errmsg='注册成功')


@passport_blue.route('/login',methods=['POST'])
def login():
    mobile=request.json.get('mobile')
    password=request.json.get('password')
    print(mobile)
    if not all([mobile,password]):
        return jsonify(errno=RET.PARAMERR,errmsg='参数不全')
    if not re.match('1[3456789]\d{9}$',mobile):
        return jsonify(errno=RET.PARAMERR,errmsg='手机号格式不匹配')
    # 是否注册
    try:
        user=User.query.filter_by(mobile=mobile).first()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=RET.DBERR,errmsg='查询数据失败')
    # if user is  None:
    #     return jsonify(errno=RET.DATAEXIST,errmsg='用户没有注册')
    #     # 获取redis中的手机号，密码，对比
    # if  not user.check_password(password):
    #     return jsonify(errno=RET.DATAERR,errmsg='密码有误')
    if user is None or not user.check_password(password):
        return jsonify(errno=RET.PARAMERR,errmsg='用户名或密码错误')

    # 7、保存用户的登录时间，提交数据到mysql数据库
    # 8、实现状态保持
    # 9、返回结果
    user.last_login=datetime.datetime.now()
    try:
        db.session.add(user)
        db.session.commit()
    except Exception as e:
        current_app.logger.error(e)
        db.session.rollback()
        return jsonify(errno=RET.DBERR,eremsg='提交数据库失败')
    session['user_id']=user.id
    session['mobile']=mobile
    session['nick_name']=user.nick_name
    return jsonify(errno=RET.OK,errmsg='登陆成功')

# 退出
@passport_blue.route('/logout')
def logout():
    session.pop('user_id')
    session.pop('mobile')
    session.pop('nick_name')
    return jsonify(errno=RET.OK,errmsg ='退出成功')
    pass



